/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.MrpMps;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import merlion.common.util.Consts;
import merlion.mrp.ppm.entity.DailyMPS;
import merlion.mrp.ppm.session.MPSPlanningSessionLocal;

/**
 *
 * @author Zhang Ying
 */
@ManagedBean
@ViewScoped
public class DailyMpsViewManagerBean {

    public static final String VIEWED_DMPS = "viewedDailyMPS";
    public static final String EDITED_DMPS = "editedDailyMPS";
    @EJB
    private MPSPlanningSessionLocal mspSession;
    // for selection page
    private String selectedDMPSStr;
    private DailyMPS viewedMPS;
    private Collection<DailyMPS> allDMPS;
    // for detail page
    private DailyMPS selectedMPS;
    private ArrayList<Integer> counterForProduct;
    private ArrayList<Integer> counterForWeek;
    private ArrayList<Long> monthlyDemands;
    private Integer totalWorkingDays;
    private ArrayList<Timestamp> times;
    private ArrayList<ArrayList<Long>> dailyDemands;
    private ArrayList<ArrayList<Long>> dailyOTDemands;
    // for select for edit page
    private DailyMPS editedMPS;

    /** Creates a new instance of DailyMpsViewManagerBean */
    public DailyMpsViewManagerBean() {
        counterForProduct = new ArrayList<Integer>();
        for (int i = 0; i < 4; i++) {
            counterForProduct.add(i);
        }
        counterForWeek = new ArrayList<Integer>();
        for (int i = 0; i < 5; i++) {
            counterForWeek.add(i);
        }
    }

    // for viewing page
    public String redirectToViewDMPSDetail() {
        if (selectedDMPSStr == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Please select daily master production schedule."));
            return null;
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(VIEWED_DMPS);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(VIEWED_DMPS, viewedMPS);
        return getRedirectPath(Consts.VIEW_DAILY_MPS_PATH + "Detail");
    }

    public String getSelectedDMPSStr() {
        return selectedDMPSStr;
    }

    public void setSelectedDMPSStr(String selectedDMPSStr) {
        this.selectedDMPSStr = selectedDMPSStr;
    }

    public DailyMPS getViewedMPS() {
        return viewedMPS;
    }

    public void setViewedMPS(DailyMPS viewedMPS) {
        this.viewedMPS = viewedMPS;
        this.selectedDMPSStr = viewedMPS.getDailyMPSIdStr();
    }

    public Collection<DailyMPS> getAllDMPS() {
        if (allDMPS == null) {
            allDMPS = mspSession.getAllDailyMPS();
        }
        return allDMPS;
    }

    public void setAllDMPS(Collection<DailyMPS> allDMPS) {
        this.allDMPS = allDMPS;
    }

    // for detail page
    public DailyMPS getSelectedMPS() {
        if (selectedMPS == null) {
            DailyMPS dmps = (DailyMPS) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(VIEWED_DMPS);
            if (dmps != null) {
                selectedMPS = dmps;
            }
        }
        return selectedMPS;
    }

    public void setSelectedMPS(DailyMPS selectedMPS) {
        this.selectedMPS = selectedMPS;
    }

    public Integer getTotalWorkingDays() {
        if (totalWorkingDays == null){
            totalWorkingDays = mspSession.getTotalWorkingDaysForMonth(getSelectedMPS().getStartPeriodMonth(), selectedMPS.getStartPeriodYear());
        }
        return totalWorkingDays;
    }

    public ArrayList<Timestamp> getTimes() {
        if (times == null) {
            times = mspSession.getDatesforWeek(getSelectedMPS().getStartPeriodYear(), selectedMPS.getStartPeriodMonth(), selectedMPS.getStartPeriodDate());
        }
        return times;
    }

    public ArrayList<Integer> getCounterForProduct() {
        return counterForProduct;
    }

    public ArrayList<Integer> getCounterForWeek() {
        return counterForWeek;
    }

    public ArrayList<ArrayList<Long>> getDailyDemands() {
        if (dailyDemands == null){
            dailyDemands = new ArrayList<ArrayList<Long>>();
            for (int i = 0; i < 4; i ++){
                ArrayList<Long> temp = new ArrayList<Long>();
                for (int j = 0; j < 5; j++){
                    temp.add(getSelectedMPS().returnIndivDMPS(i).returnDailyPlannedProduction(j).getDailyDemand());
                }
                dailyDemands.add(temp);
            }
        }
        return dailyDemands;
    }

    public ArrayList<ArrayList<Long>> getDailyOTDemands() {
        if (dailyOTDemands == null){
            dailyOTDemands = new ArrayList<ArrayList<Long>>();
            for (int i = 0; i < 4; i ++){
                ArrayList<Long> temp = new ArrayList<Long>();
                for (int j = 0; j < 5; j++){
                    temp.add(getSelectedMPS().returnIndivDMPS(i).returnDailyPlannedProduction(j).getDailyOTDemand());
                }
                dailyOTDemands.add(temp);
            }
        }
        return dailyOTDemands;
    }

    public ArrayList<Long> getMonthlyDemands() {
        if (monthlyDemands == null) {
            monthlyDemands = mspSession.getMonthlyDemand(getSelectedMPS().getStartPeriodMonth(), getSelectedMPS().getStartPeriodYear());
        }
        return monthlyDemands;
    }
    
    public Integer returnNormalShift() {
        return Consts.NORMAL_SHIFT_PER_DAY;
    }

    public Integer returnOvertimeShift() {
        return Consts.OVERTIME_EXTRA_SHIFT_PER_DAY;
    }

    public Double returnDailyDemandInHours(Long dailyDemand, int productCounter) {
        if (productCounter == 0) {
            return (1.0 * dailyDemand / Consts.CASES_PER_HOUR_CLASSIC);
        } else if (productCounter == 1) {
            return (1.0 * dailyDemand / Consts.CASES_PER_HOUR_CLASSIC);
        } else if (productCounter == 2) {
            return (1.0 * dailyDemand / Consts.CASES_PER_HOUR_PREMIUM);
        } else if (productCounter == 3) {
            return (1.0 * dailyDemand / Consts.CASES_PER_HOUR_PREMIUM);
        } else {
            return 0.0;
        }
    }

    public Double returnUtilizationNormalShift(Integer weekCount) {
        Integer totalDaysPW = 16;
        double sumOfHrs = Long.valueOf(0);
        for (int i = 0; i < 4; i++) {
            if (i == 0 || i == 1) {
                sumOfHrs += 1.0 * dailyDemands.get(i).get(weekCount) / Consts.CASES_PER_HOUR_CLASSIC;
            } else {
                sumOfHrs += 1.0 * dailyDemands.get(i).get(weekCount) / Consts.CASES_PER_HOUR_PREMIUM;
            }
        }
        if (totalDaysPW == 0) {
            return null;
        }
        return 1.0 * sumOfHrs / totalDaysPW;
    }

    public Double returnUtilizationOvertimeShift(Integer weekCount) {
        Integer totalDaysPW = 8;
        double sumOfHrs = Long.valueOf(0);
        for (int i = 0; i < 4; i++) {
            if (i == 0 || i == 1) {
                sumOfHrs += 1.0 * dailyOTDemands.get(i).get(weekCount) / Consts.CASES_PER_HOUR_CLASSIC;
            } else {
                sumOfHrs += 1.0 * dailyOTDemands.get(i).get(weekCount) / Consts.CASES_PER_HOUR_PREMIUM;
            }
        }
        if (totalDaysPW == 0) {
            return null;
        }
        return 1.0 * sumOfHrs / totalDaysPW;
    }
    
    // for select for edit
    public String redirectToEditDMPSDetail(){
        if (selectedDMPSStr == null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Please select daily master production schedule."));
            return null;
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(EDITED_DMPS);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(EDITED_DMPS, editedMPS);
        return getRedirectPath(Consts.EDIT_DAILY_MPS_PATH + "Detail");
    }

    public DailyMPS getEditedMPS() {
        return editedMPS;
    }

    public void setEditedMPS(DailyMPS editedMPS) {
        this.editedMPS = editedMPS;
        this.selectedDMPSStr = editedMPS.getDailyMPSIdStr();
    }

    // for general purpose
    private Long roundToLong(Double d) {
        return Math.round(d);
    }

    private String getRedirectPath(String path) {
        return path + "?faces-redirect=true";
    }

    private String getMonthEnglish(int i) {
        switch (i) {
            case 1:
                return Consts.JAN;
            case 2:
                return Consts.FEB;
            case 3:
                return Consts.MAR;
            case 4:
                return Consts.APR;
            case 5:
                return Consts.MAY;
            case 6:
                return Consts.JUN;
            case 7:
                return Consts.JUL;
            case 8:
                return Consts.AUG;
            case 9:
                return Consts.SEP;
            case 10:
                return Consts.OCT;
            case 11:
                return Consts.NOV;
            case 12:
                return Consts.DEC;
            default:
                return "";
        }
    }

    private int getMonthIndex(String label) {
        if (label.equals(Consts.JAN)) {
            return 1;
        } else if (label.equals(Consts.FEB)) {
            return 2;
        } else if (label.equals(Consts.MAR)) {
            return 3;
        } else if (label.equals(Consts.APR)) {
            return 4;
        } else if (label.equals(Consts.MAY)) {
            return 5;
        } else if (label.equals(Consts.JUN)) {
            return 6;
        } else if (label.equals(Consts.JUL)) {
            return 7;
        } else if (label.equals(Consts.AUG)) {
            return 8;
        } else if (label.equals(Consts.SEP)) {
            return 9;
        } else if (label.equals(Consts.OCT)) {
            return 10;
        } else if (label.equals(Consts.NOV)) {
            return 11;
        } else if (label.equals(Consts.DEC)) {
            return 12;
        } else {
            return 0;
        }
    }

    public String returnProductAlpha(Integer i) {
        if (i.intValue() == 0) {
            //return Consts.ProductType.BAR_A.getText();
            return "A";
        } else if (i.intValue() == 1) {
            //return Consts.ProductType.BAR_B.getText();
            return "B";
        } else if (i.intValue() == 2) {
            //return Consts.ProductType.BAR_C.getText();
            return "C";
        } else if (i.intValue() == 3) {
            //return Consts.ProductType.BAR_D.getText();
            return "D";
        } else {
            return "";
        }
    }

    public String returnProductName(Integer i) {
        if (i.intValue() == 0) {
            return Consts.ProductType.BAR_A.getText();
        } else if (i.intValue() == 1) {
            return Consts.ProductType.BAR_B.getText();
        } else if (i.intValue() == 2) {
            return Consts.ProductType.BAR_C.getText();
        } else if (i.intValue() == 3) {
            return Consts.ProductType.BAR_D.getText();
        } else {
            return "";
        }
    }

    public String returnFormattedDay(Timestamp t) {
        if (t == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
        return sdf.format(t);
    }
}
